package com.nami.logic.service.impl;


import cn.hutool.core.collection.CollUtil;
import com.nami.basic.constants.DownTopicConst;
import com.nami.gate.api.service.RemoteLoginService;
import com.nami.logic.bo.send.PacketTransBO;
import com.nami.logic.service.DownMsgSender;
import com.nami.logic.service.SendFailHandler;
import com.nami.logic.service.UserService;
import com.nami.store.api.bo.UserDevice;
import com.nami.store.api.bo.UserWrap;
import com.nami.store.api.request.cache.CacheDelReq;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.rpc.cluster.specifyaddress.Address;
import org.apache.dubbo.rpc.cluster.specifyaddress.UserSpecifiedAddressUtil;
import org.dromara.common.core.utils.IdentityUtil;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 描述：
 *
 * @Author: lbc
 * @Date: 2023-08-18 9:15
 * @email: 594599620@qq.com
 * @Description: keep coding
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class SendMsgFailHandlerImpl implements SendFailHandler {

    private final DownMsgSender sender;

    private final UserService userService;

    @Override
    public void handleFailSend(List<PacketTransBO> transTask) {
        try {
            for (PacketTransBO packetTransBO : transTask) {
//                log.info("[qos-fail] 准备移除用户[{}]在线状态.", packetTransBO.getIdentityNo());
                if (StringUtils.isBlank(packetTransBO.getIdentityNo())) {
                    log.error("[qos-fail] 结束假在线用户【{}】失败, 丢失参数identityNo", packetTransBO.getIdentityNo());
                    continue;
                }
                if (StringUtils.isBlank(packetTransBO.getAppKey())) {
                    log.error("[qos-fail] 结束假在线用户【{}】失败, 丢失参数appKey", packetTransBO.getIdentityNo());
                    continue;
                }

                final UserWrap user = userService.getOnrUserById(packetTransBO.getAppKey(), IdentityUtil.getUserId(packetTransBO.getIdentityNo()));
                if (user == null) {
                    log.warn("[qos-fail] 用户下线了。 appKey={}, userId={}", packetTransBO.getAppKey(), packetTransBO.getIdentityNo());
                    return;
                }
                List<UserDevice> devices = user.getDeviceInfos();
                if (CollUtil.isEmpty(devices)) {
                    return;
                }
                Integer deviceType = IdentityUtil.getDeviceType(packetTransBO.getIdentityNo());
                UserDevice deviceInfo = devices.stream()
                    .filter(item -> item != null && item.getDeviceType().equals(deviceType))
                    .collect(Collectors.toSet()).stream().findFirst().orElse(null);
                if (deviceInfo == null) {
                    return;
                }
                CacheDelReq request = new CacheDelReq();
                request.setAppKey(packetTransBO.getAppKey());
                request.setUserId(IdentityUtil.getUserId(packetTransBO.getIdentityNo()));
                request.setDeviceType(IdentityUtil.getDeviceType(packetTransBO.getIdentityNo()));
                Boolean result = userService.removeOfflineUser(request); // 返回true则为，删除了缓存数据。false代表 缓存就没有数据，没有执行删除操作
                if (!result) {
                    return;
                }
                // 关闭channel
//                sendCloseChannel(packetTransBO.getIdentityNo(), packetTransBO.getDubboIp(), packetTransBO.getDubboPort());
                log.info("[qos-fail] 发送失败策略。关闭通道。identityNo={}", packetTransBO.getIdentityNo());
                sender.syncSendByMq(DownTopicConst.CLOSE_CHANNEL_TOPIC, packetTransBO.getMqTags(), packetTransBO.getIdentityNo());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("[qos-fail] 移除用户在线状态发生异常. e:{}", e.getMessage());
        }

    }

    @Deprecated
    private void sendCloseChannel(String identityNo, String dubboIp, Integer dubboPort) {
        // 调用绑定得长连接服务器
        ReferenceConfig<RemoteLoginService> referenceConfig = new ReferenceConfig<>();
        referenceConfig.setInterface(RemoteLoginService.class);
        RemoteLoginService channelManager = referenceConfig.get();

        UserSpecifiedAddressUtil.setAddress(new Address(dubboIp, dubboPort, true));

        channelManager.closeChannel(identityNo);
    }

}
